package cc.rengu.igas.bomp.core.service.trans;

import cc.rengu.igas.bomp.common.constant.TableNameConstant;
import cc.rengu.igas.bomp.common.dao.BizHistoryMapper;
import cc.rengu.igas.bomp.common.dao.BizTmpMapper;
import cc.rengu.igas.bomp.common.dao.MchntBaseInfoMapper;
import cc.rengu.igas.bomp.common.dao.impl.BizHistoryMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.BizTmpMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntBaseInfoMapperImpl;
import cc.rengu.igas.bomp.common.entity.BizHistory;
import cc.rengu.igas.bomp.common.entity.BizTmp;
import cc.rengu.igas.bomp.common.entity.MchntBaseInfo;
import cc.rengu.igas.bomp.common.enums.AuditStatusEnum;
import cc.rengu.igas.bomp.common.enums.BizTmpStatusEnum;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.common.util.ChangeNextStatusUtil;
import cc.rengu.igas.bomp.common.util.CompareFieldsUtil;
import cc.rengu.igas.bomp.common.util.InitParamUtil;
import cc.rengu.igas.bomp.core.service.base.AuditService;
import cc.rengu.igas.bomp.facade.enums.BompMchntStatusEnum;
import cc.rengu.igas.bomp.facade.enums.BompMchntStatusOprTypeEnum;
import cc.rengu.igas.bomp.facade.request.MchntStatusManageRequest;
import cc.rengu.igas.bomp.facade.response.MchntStatusManageResponse;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSONObject;

/**
 * 商户状态管理.
 */
public class MchntStatusManageService extends AuditService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        MchntStatusManageRequest request = new MchntStatusManageRequest();
        ConvertUtil.convertOutput(request);
        return request;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MchntStatusManageRequest mchntStatusManageRequest = (MchntStatusManageRequest) request;
        MchntStatusManageResponse mchntStatusManageResponse = new MchntStatusManageResponse();
        BizResponse bizResponse = new BizResponse();
        bizResponse.setResult(mchntStatusManageResponse);
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();

        String mchntNo = mchntStatusManageRequest.getMchntNo();
        MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
        MchntBaseInfo dbMchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(mchntStatusManageRequest.getHeader().getInstId(), mchntNo);
        if (null == dbMchntBaseInfo) {
            rglog.error("修改商户状态信息失败, 根据商户号查询商户信息为空，instId:{},mchntNo:{}",
                    mchntStatusManageRequest.getHeader().getInstId(), mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }

        if (BompMchntStatusEnum.CANCEL.getType().equals(dbMchntBaseInfo.getMchntStatus())) {
            rglog.error("修改商户状态失败, 根据商户号查询商户状态为已注销，instId:{},mchntNo:{}", dbMchntBaseInfo.getInstId(), dbMchntBaseInfo.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_CANCEL.getRespCode(), RespCodeEnum.MCHNT_CANCEL.getRespDesc());
        }

        //判断当前状态是否允许修改
        if (!ChangeNextStatusUtil.isAllowModifyData(dbMchntBaseInfo.getAuditStatus())) {
            rglog.error("修改商户状态失败, 当前商户信息待审核，不允许修改，instId:{},mchntNo:{},当前商户审核状态:{}",
                    dbMchntBaseInfo.getInstId(), dbMchntBaseInfo.getMchntNo(), dbMchntBaseInfo.getAuditStatus());
            throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
        }

        String auditStatus = "";
        //待处理的数据
        MchntBaseInfo tempMchntBaseInfo = new MchntBaseInfo();
        BeanUtil.beanCopy(dbMchntBaseInfo, tempMchntBaseInfo);
        tempMchntBaseInfo.setAuditStatus(AuditStatusEnum.MODIFY_BE_AUDIT.getAuditStatus());
        tempMchntBaseInfo.setLastOprId(mchntStatusManageRequest.getUserId());
        tempMchntBaseInfo.setLastUpdateTime(DateUtil.getCurrentDateTime(InitParamUtil.yyyy_MM_dd_HHmmssSSS));
        String bizOpr;
        if (BompMchntStatusOprTypeEnum.CANCEL.getType().equals(mchntStatusManageRequest.getOprType())) {
            //注销商户基本信息
            tempMchntBaseInfo.setMchntStatus(BompMchntStatusEnum.CANCEL.getType());
            tempMchntBaseInfo.setAuditStatus(AuditStatusEnum.CANCEL_BE_AUDDIT.getAuditStatus());
            tempMchntBaseInfo.setMchntCancelReason(mchntStatusManageRequest.getMchntCancelReason());
            auditStatus = AuditStatusEnum.CANCEL_BE_AUDDIT.getAuditStatus();
            bizOpr = "C";
        } else if (BompMchntStatusOprTypeEnum.DISABLE.getType().equals(mchntStatusManageRequest.getOprType())) {
            if (!BompMchntStatusEnum.NORMAL.getType().equals(dbMchntBaseInfo.getMchntStatus())) {
                rglog.error("修改商户状态失败, 根据商户号查询商户状态为非正式商户，不允许改为停用，instId:{},mchntNo:{}", dbMchntBaseInfo.getInstId(), dbMchntBaseInfo.getMchntNo());
                throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespDesc());
            }

            //停用商户基本信息
            auditStatus = AuditStatusEnum.STOP_BE_AUDIT.getAuditStatus();
            tempMchntBaseInfo.setMchntStatus(BompMchntStatusEnum.DISABLE.getType());
            tempMchntBaseInfo.setAuditStatus(AuditStatusEnum.STOP_BE_AUDIT.getAuditStatus());
            tempMchntBaseInfo.setMchntStopReason(mchntStatusManageRequest.getMchntStopReason());
            bizOpr = "D";
        } else if (BompMchntStatusOprTypeEnum.ENABLE.getType().equals(mchntStatusManageRequest.getOprType())) {
            if (!BompMchntStatusEnum.DISABLE.getType().equals(dbMchntBaseInfo.getMchntStatus())) {
                rglog.error("修改商户状态失败, 根据商户号查询商户状态为非停用，不允许改为启用，instId:{},mchntNo:{}", dbMchntBaseInfo.getInstId(), dbMchntBaseInfo.getMchntNo());
                throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespDesc());
            }
            //启用商户基本信息  -> 正式商户
            auditStatus = AuditStatusEnum.ENABLE_BE_AUDIT.getAuditStatus();
            tempMchntBaseInfo.setMchntStatus(BompMchntStatusEnum.NORMAL.getType());
            tempMchntBaseInfo.setAuditStatus(AuditStatusEnum.ENABLE_BE_AUDIT.getAuditStatus());
            bizOpr = "E";
        } else {
            rglog.error("修改商户状态失败,传入的操作类型有误，instId:{},mchntNo:{},oprType:{}",
                    dbMchntBaseInfo.getInstId(), dbMchntBaseInfo.getMchntNo(), mchntStatusManageRequest.getOprType());
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        BizTmp bizTmp = new BizTmp();
        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
        //先查后更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
        BizTmp oldBizTemp = bizTmpMapper.selectBizTmpByRealId(tempMchntBaseInfo.getInstId(), tempMchntBaseInfo.getId());
        if (null != oldBizTemp) {
            BeanUtil.beanCopy(oldBizTemp, bizTmp);
            ConvertUtil.convertOutput(bizTmp);
        } else {
            ConvertUtil.convertOutput(bizTmp);
            BeanUtil.beanCopy(tempMchntBaseInfo, bizTmp);
            bizTmp.setManageInstId(tempMchntBaseInfo.getSignInstId());
            bizTmp.setRealId(tempMchntBaseInfo.getId());
            bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_BASE_INFO);
        }
        bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
        //修改
        bizTmp.setBizOpr(bizOpr);
        //修改待审批
        bizTmp.setAuditStatus(tempMchntBaseInfo.getAuditStatus());
        bizTmp.setLastOprId(mchntStatusManageRequest.getUserId());
        bizTmp.setLastUpdateTime(DateUtil.getCurrentDateTime(InitParamUtil.yyyy_MM_dd_HHmmssSSS));
        //将待修改的商户信息存入 bizTmp
        String modifyMchntBaseInfo = JSONObject.toJSONString(tempMchntBaseInfo);
        InitParamUtil.initBizTempData(bizTmp, modifyMchntBaseInfo);

        BizHistory bizHistory = new BizHistory();
        BeanUtil.beanCopy(bizTmp, bizHistory);
        //将正式表的商户信息存入历史表 bizData
        String compare = CompareFieldsUtil.compareFields(dbMchntBaseInfo, modifyMchntBaseInfo, null);
        InitParamUtil.initBizHistoryData(bizHistory, compare);


        //需要审核， 更新正式表的信息为修改待审核， 将传入的商户信息更新到业务临时表
        //原商户信息改为 xx待审核
        dbMchntBaseInfo.setAuditStatus(auditStatus);
        dbMchntBaseInfo.setLastOprId(mchntStatusManageRequest.getUserId());
        dbMchntBaseInfo.setLastUpdateTime(DateUtil.getCurrentDateTime(InitParamUtil.yyyy_MM_dd_HHmmssSSS));
        modifyMchntBaseInfoForMchntStatus(xmlTreeUtil, dbMchntBaseInfo, bizTmp, null);


        mchntStatusManageResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        mchntStatusManageResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    private void modifyMchntBaseInfoForMchntStatus(XmlTreeUtil xmlTreeUtil,
                                                   MchntBaseInfo mchntBaseInfo,
                                                   BizTmp bizTmp,
                                                   BizHistory bizHistory) throws Exception {
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.MCMP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.MCMP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        try {
            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            int dbResult = mchntBaseInfoMapper.updateMchntBaseInfoById(mchntBaseInfo);
            if (dbResult != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("修改商户基本信息表-商户状态失败！id:{},mchnt:{},instId:{}",
                        mchntBaseInfo.getId(), mchntBaseInfo.getMchntNo(), mchntBaseInfo.getInstId());
                throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
            }

            if (null != bizTmp) {
                BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
                //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
                BizTmp oldBizTemp = bizTmpMapper.selectBizTmpByRealId(bizTmp.getInstId(), bizTmp.getRealId());
                if (null == oldBizTemp) {
                    dbResult = bizTmpMapper.insertBizTmp(bizTmp);
                } else {
                    dbResult = bizTmpMapper.updateBizTmpByRealId(bizTmp);
                }

                if (dbResult != 0) {
                    dbsUtil.dbsEndTransaction(false);
                    rglog.error("修改商户基本信息商户状态失败-登记/更新临时表记录失败！realId:{},manageInstId:{},instId:{}",
                            bizTmp.getRealId(), bizTmp.getManageInstId(), bizTmp.getInstId());
                    throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                }
            }

            if (null != bizHistory) {
                BizHistoryMapper bizHistoryMapper = new BizHistoryMapperImpl();

                dbResult = bizHistoryMapper.insertBompBizHistory(bizHistory);
                if (dbResult != 0) {
                    dbsUtil.dbsEndTransaction(false);
                    rglog.error("修改商户基本信息-修改商户状态-业务历史表记录失败！realId:{},manageInstId:{},instId:{}",
                            bizHistory.getRealId(), bizHistory.getManageInstId(), bizHistory.getInstId());
                    throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                }
            }

            dbsUtil.dbsEndTransaction(true);
        } catch (Exception e) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("商户状态管理失败！ e:{}", e.getMessage());
            throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
        }
    }


    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MchntStatusManageResponse mchntStatusManageResponse = (MchntStatusManageResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mchntStatusManageResponse);
    }
}
